#region File Description
//-----------------------------------------------------------------------------
// SpinningTriangleControl.cs
//
// Microsoft XNA Community Game Platform
// Copyright (C) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
#endregion

#region Using Statements
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Diagnostics;
using System.Windows.Forms;
#endregion

namespace Sparklings.LevelEditor
{
    /// <summary>
    /// Example control inherits from GraphicsDeviceControl, which allows it to
    /// render using a GraphicsDevice. This control shows how to draw animating
    /// 3D graphics inside a WinForms application. It hooks the Application.Idle
    /// event, using this to invalidate the control, which will cause the animation
    /// to constantly redraw.
    /// </summary>
    class SparklingsGameControl : GraphicsDeviceControl
    {
        Timer testLevelTimer;
        Stopwatch timer;
        TimeSpan lastTime;
        LevelNeededData levelNeededData;
        public Level level;
        bool mouseDown;
        string levelBeforeTestMode;

        /// <summary>
        /// Initializes the control.
        /// </summary>
        protected override void Initialize()
        {
            levelNeededData = new LevelNeededData()
                {
                    Content = new ContentManager(Services, "Content"),
                    GraphicsDevice = GraphicsDevice,
                    RNG = new Random()
                };

            testLevelTimer = new Timer();
            testLevelTimer.Interval = 1000/60;

            // Hook the idle event to constantly redraw our animation.
            testLevelTimer.Tick += (o, e) => Invalidate();

            //Application.Idle += delegate { if (timer != null ) Invalidate(); };
            MouseClick += delegate(object o, MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Right)
                {
                    if (((MainForm)Parent).InPlayMode) return;
                    Vector2 mousePos = level.RenderContext.FromScreenPosition(GetMouseInLocal());
                    ((MainForm)Parent).GetCurrentTileType().Place(level, (int)mousePos.X, (int)mousePos.Y, (MainForm)Parent);
                    Invalidate();
                }
            };
            mouseDown = false;
            LostFocus += (x, y) => mouseDown = false;
            MouseDown += delegate(object o, MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Left)
                {
                    mouseDown = true;
                }
            };
            MouseUp += delegate(object o, MouseEventArgs e)
            {
                if (e.Button == MouseButtons.Left)
                {
                    mouseDown = false;
                }
            };
            level = new Level(levelNeededData, 5, 5);
            ((MainForm)Parent).TestModeChanged += delegate
            {
                if (((MainForm)Parent).InPlayMode)
                {
                    timer = Stopwatch.StartNew();
                    levelBeforeTestMode = level.Save();
                    testLevelTimer.Start();
                }
                else
                {
                    testLevelTimer.Stop();
                    timer = null;
                    level = Level.Load(levelNeededData,levelBeforeTestMode);
                    Invalidate();
                }
            };
        }

        protected Vector2 GetMouseInLocal()
        {
            return new Vector2(this.PointToClient(Control.MousePosition).X, this.PointToClient(Control.MousePosition).Y);
        }

        /// <summary>
        /// Draws the control.
        /// </summary>
        protected override void Draw()
        {
            level.RenderBounds = new Vector2(Width, Height);
            if (((MainForm)Parent).InPlayMode)
            {
                GameTime gt = new GameTime(timer.Elapsed, timer.Elapsed - lastTime);
                if (gt.ElapsedGameTime.Seconds>0.1)
                {
                    gt = new GameTime(timer.Elapsed,new TimeSpan(1000));
                }
                level.Update(
                    gt,
                    GetMouseInLocal(), mouseDown);
                lastTime = timer.Elapsed;
            }
            GraphicsDevice.Clear(Color.CornflowerBlue);
            Texture2D t = level.GetDrawn(GraphicsDevice);
            using (var b = new SpriteBatch(GraphicsDevice))
            {
                b.Begin();
                b.Draw(t, new Vector2(0), Color.White);
                b.End();
            }
        }

        public void LoadLevel(string jsonLevel)
        {
            level = Level.Load(levelNeededData, jsonLevel);
            Invalidate();
        }
        public string SaveLevel()
        {
            return level.Save();
        }
        public void NewLevel(int x, int y)
        {
            level = new Level(levelNeededData, x, y);
            Invalidate();
        }
    }
}
